package com.sihai.ehr.utils;

import com.sihai.ehr.model.biz.ExamEmbedPeriod;
import com.sihai.ehr.model.biz.ExamPeriod;
import com.sihai.ehr.model.sys.ExaminePeriodEnum;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 周期操作工具
 * 
 * @author: wxn
 * @since: 12-10-25 Time: 下午5:47
 */
public class PeriodUtils {
	/** 双月存入月分数 */
	private static int[] bimonthlys_p = { 12, 2, 4, 6, 8, 10 };
	/** 季度存入月分数 */
	private static int[] seasons_p = { 12, 3, 6, 9 };
	/** 半年存入月分数 */
	private static int[] semiyearly_p = { 12, 6 };

    public static int getCountByPeriodType(ExaminePeriodEnum periodType){
        if(periodType == ExaminePeriodEnum.monthly){
            return 1;
        }else if(periodType == ExaminePeriodEnum.bimonthly){
            return 2;
        }else if(periodType == ExaminePeriodEnum.season){
            return 3;
        }else if(periodType == ExaminePeriodEnum.semiyearly){
            return 6;
        }else if(periodType == ExaminePeriodEnum.annually){
            return 12;
        }
        return -1;
    }

	/**
	 * 创建一个小周期
	 * 
	 * @param examPeriodStr
	 *            : 2012年8月或-1(当前周期)
	 * @param examPeriodEnum
	 *            周期类型
	 * @return
	 */
	public static ExamEmbedPeriod createEmbedPeriod(String examPeriodStr,
			ExaminePeriodEnum examPeriodEnum) {
		if (StringUtils.isBlank(examPeriodStr) || examPeriodEnum == null) {
			return null;
		}

		ExamEmbedPeriod embedPeriod = new ExamEmbedPeriod();
		embedPeriod.setPeriodType(examPeriodEnum);

		Calendar calendar = Calendar.getInstance();
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) + 1;

		boolean flag = (month - 1 > 0);

		if (StringUtils.equals(examPeriodStr, "-1")) {
			if (examPeriodEnum == ExaminePeriodEnum.monthly) {
				int y = flag ? year : year - 1;
				int m = flag ? month - 1 : 12;
				embedPeriod.setPeriodName(String.format("%s年%s月", y, m));
			} else if (examPeriodEnum == ExaminePeriodEnum.bimonthly) {// 双月
				if (month % 2 != 1) {// 1,3,5,7,9,11
					return null;
				}
				if (flag) {
					embedPeriod.setPeriodName(String.format("%s年%s~%s月", year,
							month - 2, month - 1));
				} else {
					embedPeriod.setPeriodName(String.format("%s年11~12月",
							year - 1));
				}
			} else if (examPeriodEnum == ExaminePeriodEnum.season) {// 季
				if (month % 3 != 1) {// 1,4,7,10
					return null;
				}
				if (flag) {
					embedPeriod.setPeriodName(String.format("%s年%s~%s月", year,
							month - 3, month - 1));
				} else {
					embedPeriod.setPeriodName(String.format("%s年10~12月",
							year - 1));
				}
			} else if (examPeriodEnum == ExaminePeriodEnum.semiyearly) {// 半年
				if (month % 6 != 1) {// 1,7
					return null;
				}
				if (flag) {
					embedPeriod.setPeriodName(String.format("%s年1~6月", year));
				} else {
					embedPeriod.setPeriodName(String.format("%s年7~12月",
							year - 1));
				}
			} else if (examPeriodEnum == ExaminePeriodEnum.annually) {// 年
				if (month != 1) {// 1
					return null;
				}
				embedPeriod.setPeriodName(String.format("%s年1~2月", year - 1));
			}
		} else {
			embedPeriod.setPeriodName(examPeriodStr);
		}

		return embedPeriod;
	}

	/**
	 * 通过小周期得到其所属的大周期(即通过ExamEmbedPeriod和周期类型创建一个ExamPeriod)
	 * 
	 * @param embedPeriod [name: 2012年7~8月, type=bimonthly]
	 * @param maxPeriodEnum 大周期，如season
	 * @return [name: 2012年8月, year=2012, month=8, type=bimonthly]
	 */
	public static ExamPeriod createPeriod(ExamEmbedPeriod embedPeriod, ExaminePeriodEnum maxPeriodEnum) {
		if (embedPeriod == null) {
			return null;
		}
		ExamPeriod period = new ExamPeriod();
		ExaminePeriodEnum periodEnum = embedPeriod.getPeriodType();
		String periodStr = embedPeriod.getPeriodName();
		int y = NumberUtils.createInteger(StringUtils.substring(periodStr, 0, 4));
		int m = 0;
		if (periodEnum == ExaminePeriodEnum.monthly) {// 月:2012年11月
			m = NumberUtils.createInteger(StringUtils.substring(periodStr, 5, periodStr.length() - 1));
		} else {// 双月:2012年9~10月, 季:2012年10~12月, 半年:2012年1~6月, 年:2012年1~12月
			m = NumberUtils.createInteger(StringUtils.substring(periodStr, periodStr.indexOf("~")+1, periodStr.length() - 1));
		}

		// m为小周期的最后一个月
		int mm = m;
		if (maxPeriodEnum == ExaminePeriodEnum.bimonthly) {
			if (periodEnum == ExaminePeriodEnum.monthly) {
				mm = (m % 2 == 0 ? m : m + 1);
			} else {
				mm = m;
			}
		} else if (maxPeriodEnum == ExaminePeriodEnum.season) {
			if (m <= 3) {
				mm = 3;
			} else if (m <= 6) {
				mm = 6;
			} else if (m <= 9) {
				mm = 9;
			} else if (m <= 12) {
				mm = 12;
			}
		} else if (maxPeriodEnum == ExaminePeriodEnum.semiyearly) {
			if (m <= 6) {
				mm = 6;
			} else {
				mm = 12;
			}
		} else if (maxPeriodEnum == ExaminePeriodEnum.annually) {
			mm = 12;
		}

		period.setPeriodType(maxPeriodEnum);
		period.setExamYear(y);
		period.setExamMonthly(mm);
		period.setPeriodName(String.format("%s年%s月", y, mm));

		return period;
	}

	/**
	 * 得取最近三期的虚拟周期
	 * 
	 * @param periodEnum
	 * @param yearly
	 *            当前年
	 * @param monthly
	 *            当前月
	 * @return
	 */
	public static List<ExamPeriod> getLateThreeExamPeriod(
			ExaminePeriodEnum periodEnum, int yearly, int monthly) {
		List<ExamPeriod> periods = new ArrayList<ExamPeriod>();
		if (periodEnum == ExaminePeriodEnum.monthly) {
			int j = 0;
			int mm = monthly - 1;
			int yy = yearly;
			while (j < 3) {
				if (mm <= 0) {
					mm = 12 + mm;
					yy = yy - 1;
				}
				ExamPeriod examPeriod = new ExamPeriod();
				examPeriod.setPeriodName(MessageFormat.format(
						ExaminePeriodEnum.monthly.getPeriodFormat(), yy, mm));
				examPeriod.setPeriodType(periodEnum);
				examPeriod.setExamYear(yy);
				examPeriod.setExamMonthly(mm);
				periods.add(examPeriod);
				j++;
				mm--;
			}
		} else if (periodEnum == ExaminePeriodEnum.bimonthly) {
			int yy = yearly;
			int index = monthly % 2 == 0 ? (monthly - 1) / 2 : monthly / 2;
			int j = 0;
			while (j < 3) {
				if (index <= 0) {
					yy--;
				}
				ExamPeriod examPeriod = new ExamPeriod();
				examPeriod.setPeriodName(MessageFormat.format(
						ExaminePeriodEnum.bimonthly.getPeriodFormat(), yy,
						bimonthlys_p[index] - 1, bimonthlys_p[index]));
				examPeriod.setPeriodType(periodEnum);
				examPeriod.setExamYear(yy);
				examPeriod.setExamMonthly(bimonthlys_p[index]);
				periods.add(examPeriod);
				j++;
				if (index <= 0) {
					index = 5;
				} else {
					index--;
				}
			}
		} else if (periodEnum == ExaminePeriodEnum.season) {
			int yy = yearly;
			int temp = monthly % 3;
			int index = (monthly - temp) / 3;
			if(temp == 0){
                index = monthly/3 -1;
            }else if(temp == 1) { // 1,4,7,10
				index = monthly / 3;
			}
			int j = 0;
			while (j < 3) {
				if (index <= 0) {
					yy--;
				}
				ExamPeriod examPeriod = new ExamPeriod();
				examPeriod.setPeriodName(MessageFormat.format(
						ExaminePeriodEnum.season.getPeriodFormat(), yy,
						seasons_p[index] / 3));
				examPeriod.setPeriodType(periodEnum);
				examPeriod.setExamYear(yy);
				examPeriod.setExamMonthly(seasons_p[index]);
				periods.add(examPeriod);
				j++;
				if (index <= 0) {
					index = 3;
				} else {
					index--;
				}
			}
		} else if (periodEnum == ExaminePeriodEnum.semiyearly) {
			int yy = yearly;
			int index = (monthly - 1) / 6;
			int j = 0;
			while (j < 3) {
				if (index <= 0) {
					yy = yy - 1;
				}
				ExamPeriod examPeriod = new ExamPeriod();
				examPeriod.setPeriodName(MessageFormat.format(
						ExaminePeriodEnum.semiyearly.getPeriodFormat(), yy,
						seasons_p[index] / 6 > 1 ? "下" : "上"));
				examPeriod.setPeriodType(periodEnum);
				examPeriod.setExamYear(yy);
				examPeriod.setExamMonthly(semiyearly_p[index]);
				periods.add(examPeriod);
				if (index <= 0) {
					index = 2;
				}
				j++;
				index--;
			}
		} else if (periodEnum == ExaminePeriodEnum.annually) {
			int yy = yearly;
			for (int i = 0; i < 3; i++) {
				yy--;
				ExamPeriod examPeriod = new ExamPeriod();
				examPeriod.setPeriodName(MessageFormat.format(
						ExaminePeriodEnum.annually.getPeriodFormat(), yy));
				examPeriod.setPeriodType(periodEnum);
				examPeriod.setExamYear(yy);
				examPeriod.setExamMonthly(1);
				periods.add(examPeriod);
			}
		}
		return periods;
	}

	public static List<ExamPeriod> getLateThreeExamPeriodTOReverse(
			ExaminePeriodEnum periodEnum, int yearly, int monthly) {
		PeriodUtils vUtils = new PeriodUtils();
		List<ExamPeriod> examPeriods = getLateThreeExamPeriod(periodEnum,
				yearly, monthly);
		Collections.sort(examPeriods, vUtils.new CompareExamPeriod());
		return examPeriods;
	}

	class CompareExamPeriod implements Comparator<ExamPeriod> {
		@Override
		public int compare(ExamPeriod o1, ExamPeriod o2) {
			int cResult = ((Integer) o1.getExamYear()).compareTo((Integer) o2
					.getExamYear());
			if (cResult == 0) {
				return ((Integer) o1.getExamMonthly()).compareTo((Integer) o2
						.getExamMonthly());
			} else {
				return cResult;
			}
		}

	}
}
